package gemini.pollux.ui.client.page;

import gemini.pollux.ui.client.mvp.event.WidgetChangeEvent;
import gemini.pollux.ui.client.mvp.event.WidgetChangeHandler;
import gemini.pollux.ui.client.mvp.single.PolluxWidgetPresenter;
import gemini.pollux.ui.client.page.navigation.NavigationWidget;
import gemini.pollux.ui.client.page.navigation.loginwidget.LoginEvent;
import gemini.pollux.ui.client.page.navigation.loginwidget.LoginFormWidget;
import gemini.pollux.ui.client.page.navigation.loginwidget.LoginHandler;
import gemini.pollux.ui.client.page.navigation.loginwidget.LoginInfoWidget;
import gemini.pollux.ui.client.utils.UIConstants;
import gemini.pollux.ui.client.utils.UIConstants.LayoutPosition;
import ch.elca.gwt.mvp.client.EventBus;
import ch.elca.gwt.mvp.client.place.Place;
import ch.elca.gwt.mvp.client.widget.WidgetDisplay;

import com.google.gwt.user.client.ui.DialogBox;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.Widget;
import com.google.inject.Inject;

public class RootPresenter extends PolluxWidgetPresenter<RootPresenter.Display> {

    public interface Display extends WidgetDisplay {
    	void changeContent(Widget w);
    	void visibleContent(boolean b);

    	int getNavigationCount();
		void setNavigationAtIndex(Widget w, int idx, boolean replace);
		void visibleNavigation(boolean visible);
    }

	public static final Place PLACE = new Place(UIConstants.PLACE_ROOT);

	@Inject
	public RootPresenter(final Display display, final EventBus eventBus) {
		super(display, eventBus);
	}

    /*
     * Register listeners on Display actions
     */
    @Override
    protected void onBind() {
		registerHandler(eventBus.addHandler(WidgetChangeEvent.getType(),
				new WidgetChangeHandler() {
					public void onChange(
							final WidgetChangeEvent event) {
						if (event.getPosition() == null
								|| event.getPosition().equals(
										LayoutPosition.CONTENT)) {
							getDisplay().changeContent(
									event.getWidgetPresenter().getDisplay()
											.asWidget());
						} else {
							getDisplay().setNavigationAtIndex(event.getWidgetPresenter().getDisplay()
											.asWidget(), 0, false);
						}
					}
				}));
		
		registerHandler(eventBus.addHandler(RootEvent.getType(), new RootHandler() {
			
			@Override
			public void onUnMask(RootEvent event) {
				unmask();
			}
			
			@Override
			public void onMask(RootEvent event) {
				mask();
			}
		}));
		
		// must put initCustom method in the last, when all handler has registered
		initCustom();
    }
    
    private void initCustom(){
    	registerHandler(getLoginFormWidget().addLoginFormHandler(createLoginHandler()));
		registerHandler(getLoginInforWidget().addLoginFormHandler(createLoginHandler()));
		
		NavigationWidget navigation = new NavigationWidget();
		display.setNavigationAtIndex(navigation, getDisplay().getNavigationCount(), false);
		display.changeContent(new HTML("<h1>Welcome to Pollux!</h1>"));
		
		showLoginPanel();
    }
    
    private void showLoginPanel(){
    	display.visibleContent(false);
    	display.visibleNavigation(false);
    	getBox(getLoginFormWidget()).center();
    	box.setText("Login");
    	box.show();
    }
    
    private LoginHandler createLoginHandler(){
		LoginHandler result = new LoginHandler() {
			
			@Override
			public void onSuccess(LoginEvent userLoginEvent) {
				getLoginInforWidget().loadData(userLoginEvent.getLoggedInUser());
				display.setNavigationAtIndex(getLoginInforWidget(), 0, false);
				
				box.hide();

				display.visibleContent(true);
		    	display.visibleNavigation(true);
			}
			
			@Override
			public void onLogout(LoginEvent userLoginEvent) {
				showLoginPanel();
			}
		};
		return result;
	}

    @Override
    public Place getPlace() {
        return PLACE;
    }

    private DialogBox loadingBox;

	private boolean loading = false;

	public void mask() {
		if (!loading) {
			display.visibleContent(false);
			getLoadingBox().center();
			getLoadingBox().show();
			loading = true;
		}
	}

	public void unmask() {
		if (loading) {
			display.visibleContent(true);
			getLoadingBox().hide();
			loading = false;
		}
	}
	
	private DialogBox getLoadingBox() {
		if (loadingBox == null) {
			loadingBox = new DialogBox();
			loadingBox.setGlassEnabled(true);
			loadingBox.setAnimationEnabled(true);
			loadingBox.setStyleName("gwt-DialogLoading");
			Image image = new Image("images/icons/ico_loading.gif");
			image.setSize("135px", "100px");
			loadingBox.setWidget(image);
		}
		
		return loadingBox;
	}
	

    private DialogBox box;
	
	private DialogBox getBox(Widget w) {
		if (box == null) {
			box = new DialogBox();
			box.setGlassEnabled(true);
			box.setAnimationEnabled(true);
		}
		
		box.setWidget(w);
		
		return box;
	}


	private LoginFormWidget loginFormWidget;

	private LoginInfoWidget loginInforWidget;

	public LoginFormWidget getLoginFormWidget() {
		if (loginFormWidget == null) {
			loginFormWidget = new LoginFormWidget();
		}
		return loginFormWidget;
	}

	public LoginInfoWidget getLoginInforWidget() {
		if (loginInforWidget == null) {
			loginInforWidget = new LoginInfoWidget();
		}
		return loginInforWidget;
	}
}
